import 'dart:async';
import 'package:flutter/material.dart';
import 'package:qgchat/bloc/blocProvider.dart';
import 'package:qgchat/common/class/date/index.dart';
import 'package:qgchat/common/class/eventBus/index.dart';
import 'package:qgchat/common/class/toUserInfo/toUserInfo.dart';
import 'package:qgchat/common/class/websocket/index.dart';
import 'package:qgchat/common/class/websocket/videoWs.dart';
import 'package:qgchat/common/global/global.dart';
import 'package:qgchat/http/apis/video.dart';
import 'package:qgchat/http/models/giftModel.dart';
import 'package:qgchat/states/states_model/index.dart';
import 'package:qgchat/states/states_model/socket.dart';
import 'package:qgchat/widgets/gitfSvga.dart';
import 'package:wakelock/wakelock.dart';

class LiveBloc implements BlocBase {
  // ##########  STREAMS  ##############

  /// 是否显示主播资料
  StreamController _showAnchorData = StreamController<bool>();
  Sink get _showAnchorDataSink => _showAnchorData.sink;
  Stream get showAnchorDataStream => _showAnchorData.stream;

  /// 对方是否加入频道(开关对方的摄像头)
  StreamController _anchorJoined = StreamController<bool>.broadcast();
  Sink get _anchorJoinedSink => _anchorJoined.sink;
  Stream get anchorJoinedStream => _anchorJoined.stream;

  /// 开关本地的摄像头
  StreamController _showMyView = StreamController<bool>.broadcast();
  Sink get _showMyViewSink => _showMyView.sink;
  Stream get showMyViewStream => _showMyView.stream;

  /// 是否结束视频
  StreamController _closeVideo = StreamController<bool>();
  Sink get _closeVideoSink => _closeVideo.sink;
  Stream get closeVideoStream => _closeVideo.stream;

  /// 页面计时
  StreamController _viewTime = StreamController<String>();
  Sink get _viewTimeSink => _viewTime.sink;
  Stream get viewTimeStream => _viewTime.stream;

  /// 分钟计时 每分钟一跳
  StreamController _minute = StreamController<bool>();
  Sink get _minuteSink => _minute.sink;
  Stream get minuteStream => _minute.stream;

  // ##########  DEFAULT  ##############

  /// 是否显示主播资料 默认值
  final bool showAnchorDataDefault = false;

  /// 是否显示礼物窗口 默认值
  final bool showGiftBoxDefault = false;

  /// 对方是否加入频道 默认值
  final bool anchorJoinedDefault = false;

  /// 本地摄像头是否开启 默认值
  final bool myViewDefault = true;

  // ##########  HANDLING  ##############

  /// socket状态
  SocketState socketState = state(Global.context, 'socket');

  /// user状态
  UserState userState = state(Global.context, 'user');

  /// 全局websocket
  WebSocket ws = Global.ws;

  /// 计费websocket
  VideoWs videoWs;

  /// 声网实例
  var agora;

  /// 对方
  String _targetName;
  String _targetHead;
  String _targetToken;

  /// 自己是否主播
  bool _isAnchor;

  /// 邀请id
  int invId;

  /// 当前是否已开始通话
  bool isStart = false;

  /// 当前是否已关闭通话
  bool isCloseVideo = false;

  /// 页面计时定时器
  Timer timer;

  LiveBloc({
    int inv,
    int aid,
    int uid,
    String targetToken,
    String targetName,
    String targetHead,
    bool isReceive,
    bool isAnchor,
  }) {
    Wakelock.enable(); // 屏幕常亮

    socketState.toggleCallState(true);

    _isAnchor = isAnchor;
    _targetName = targetName;
    _targetHead = targetHead;
    _targetToken = targetToken;
    // agora = Agora(aid, uid, isAnchor); // 初始化声网
    videoWs = VideoWs(); // 初始化计费ws

    bus.on("gift", (data) {
      GiftModel gift = data;
      GitfSvga.show(gift.id); // 显示礼物

      GlobalState global = state(Global.context, 'global');
      List list = global.receivedGift;
      if (list.any((item) => item.id == gift.id)) {
        int i = list.indexWhere((item) => item.id == gift.id);
        list[i].number = list[i].number + gift.number;
      } else {
        list.add(gift);
      }
      global.getReceivedGift(list);
    });

    agora.onError = () {
      print('声网错误回调');
      closeVideo();
    }; // 声网错误回调
    agora.onConnectionLost = () {
      print('网络连接中断回调');
      closeVideo();
    }; // 网络连接中断回调
    // agora.onUserOffline = () {
    //   print('远端用户离开当前频道回调');
    //   // closeVideo();
    // }; // 远端用户离开当前频道回调
    ws.listenStoptalk = () {
      print('监听远端用户挂断或拒绝');
      closeVideo();
    }; // 监听远端用户挂断或拒绝
    videoWs.listenNoMoney = () {
      print('没钱回调');
      closeVideo();
    }; // 没钱回调

    // 对方开关摄像头回调
    agora.onUserEnableLocalVideo = _onUserEnableLocalVideo;

    if (isReceive) {
      // 接受者注入事件
      agora.onJoinChannelSuccess = _receiveJoin;

      // 接受者加入频道
      if (inv != null) {
        startVideo(inv: inv);
      }
    } else {
      // 发起者注入事件
      agora.onUserJoined = _onUserJoined; // 监听远端用户加入当前频道
      ws.listenInvtokening = _listenInvtokening; // 监听远端用户返回邀请id

      // 邀请对方加入频道
      ws.inviteVideo(targetToken);
    }
  }

  /// 销毁
  void dispose() {
    Wakelock.disable(); // 关闭屏幕常亮

    state(Global.context, 'global').getReceivedGift([]);
    bus.off("gift");
    agora.disposeCallBack(); // 销毁声网里注入的回调方法
    agora.destroy(); // 销毁声网
    ws.disposeCallBack(); // 销毁ws
    videoWs.dispose(); // 销毁计费ws
    timer?.cancel(); // 销毁定时器

    _showAnchorData.close();
    _anchorJoined.close();
    _showMyView.close();
    _closeVideo.close();
    _viewTime.close();
  }

  /// 开始通话
  startVideo({int inv}) {
    invId = inv;

    // 加入频道
    agora.joinChannel(inv);

    // 开始通话
    isStart = true;

    // 用户开始计费
    if (!_isAnchor) {
      String userToken = userState.info.memberToken;
      videoWs?.start(userToken, inv);
    }

    // 页面开始计时
    _viewStatisticsTime();
  }

  /// 关闭通话
  closeVideo() {
    if (!_closeVideo.isClosed && !isCloseVideo) {
      _closeVideoSink.add(true);
      isCloseVideo = true;
    }
  }

  // 开关摄像头按钮
  enableLocalVideo() {
    agora.enableLocalVideo();
    if (agora.enabled) {
      _showMyViewSink.add(true);
    } else {
      _showMyViewSink.add(false);
    }
  }

  // 开摄像头按钮
  openLocalVideo() {
    agora.openLocalVideo();
    _showMyViewSink.add(true);
  }

  // 关摄像头按钮
  closeLocalVideo() {
    agora.closeLocalVideo();
    _showMyViewSink.add(false);
  }

  // 对方开关摄像头监听
  _onUserEnableLocalVideo(bool open) {
    if (open) {
      showToast("对方开启了摄像头");
      _anchorJoinedSink.add(true);
    } else {
      showToast("对方关闭了摄像头");
      _anchorJoinedSink.add(false);
    }
  }

  /// 接受者加入频道
  _receiveJoin() {
    if (_anchorJoined != null && !_anchorJoined.isClosed) {
      _anchorJoinedSink.add(true);
    }
  }

  /// 监听远端用户加入当前频道
  _onUserJoined() {
    if (_anchorJoined != null && !_anchorJoined.isClosed) {
      _anchorJoinedSink.add(true);
    }
  }

  /// 监听远端用户返回邀请id
  _listenInvtokening(int inv) {
    startVideo(inv: inv);
  }

  /// 切换主播资料显隐
  void toggleAnchorData(BuildContext context, String targetToken) {
    ToUserInfo.show(context, targetToken);
  }

  /// 页面计时
  _viewStatisticsTime() {
    int createtime = DateTime.now().millisecondsSinceEpoch;
    int i = 0;

    timer?.cancel();
    timer = Timer.periodic(Duration(seconds: 1), (t) {
      int now = DateTime.now().millisecondsSinceEpoch;
      if (!_viewTime.isClosed) {
        i++;
        if (i % 60 == 0) {
          _minuteSink.add(true);
        }
        _viewTimeSink.add("${Date.difference(createtime, now)}");
      }
    });
  }

  // 举报主播
  reportAnthor(content) async {
    Map result = await VideoApis.reportAnthor(_targetToken, content);
    if (result['status'] == 1) {
      showToast("举报成功，官方会马上核实");
    } else {
      showToast(result['msg']);
    }
  }
}
